home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / awt / Frame.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  19.7 KB  |  676 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Frame.java    1.94 98/09/09
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package java.awt;
  15.  
  16. import java.awt.peer.FramePeer;
  17. import java.awt.event.*;
  18. import java.util.Vector;
  19. import java.io.ObjectOutputStream;
  20. import java.io.ObjectInputStream;
  21. import java.io.IOException;
  22. import sun.awt.AppContext;
  23. import java.lang.ref.WeakReference;
  24.  
  25. /**
  26.  * A Frame is a top-level window with a title and a border.
  27.  * <p>
  28.  * The size of the frame includes any area designated for the
  29.  * border.  The dimensions of the border area can be obtained 
  30.  * using the <code>getInsets</code> method, however, since 
  31.  * these dimensions are platform-dependent, a valid insets
  32.  * value cannot be obtained until the frame is made displayable
  33.  * by either calling <code>pack</code> or <code>show</code>. 
  34.  * Since the border area is included in the overall size of the
  35.  * frame, the border effectively obscures a portion of the frame,
  36.  * constraining the area available for rendering and/or displaying
  37.  * subcomponents to the rectangle which has an upper-left corner
  38.  * location of <code>(insets.left, insets.top)</code>, and has a size of
  39.  * <code>width - (insets.left + insets.right)</code> by 
  40.  * <code>height - (insets.top + insets.bottom)</code>. 
  41.  * <p>
  42.  * The default layout for a frame is BorderLayout.
  43.  * <p>
  44.  * Frames are capable of generating the following types of window events:
  45.  * WindowOpened, WindowClosing, WindowClosed, WindowIconified,
  46.  * WindowDeiconified, WindowActivated, WindowDeactivated.
  47.  *
  48.  * @version     1.94, 09/09/98
  49.  * @author     Sami Shaio
  50.  * @see WindowEvent
  51.  * @see Window#addWindowListener
  52.  * @since       JDK1.0
  53.  */
  54. public class Frame extends Window implements MenuContainer {
  55.  
  56.     /* Note: These are being obsoleted;  programs should use the Cursor class
  57.      * variables going forward. See Cursor and Component.setCursor.
  58.      */
  59.  
  60.    /**
  61.     * @deprecated   replaced by <code>Cursor.DEFAULT_CURSOR</code>.
  62.     */
  63.     public static final int    DEFAULT_CURSOR           = Cursor.DEFAULT_CURSOR;
  64.  
  65.  
  66.    /**
  67.     * @deprecated   replaced by <code>Cursor.CROSSHAIR_CURSOR</code>.
  68.     */
  69.     public static final int    CROSSHAIR_CURSOR         = Cursor.CROSSHAIR_CURSOR;
  70.  
  71.    /**
  72.     * @deprecated   replaced by <code>Cursor.TEXT_CURSOR</code>.
  73.     */
  74.     public static final int    TEXT_CURSOR              = Cursor.TEXT_CURSOR;
  75.  
  76.    /**
  77.     * @deprecated   replaced by <code>Cursor.WAIT_CURSOR</code>.
  78.     */
  79.     public static final int    WAIT_CURSOR             = Cursor.WAIT_CURSOR;
  80.  
  81.    /**
  82.     * @deprecated   replaced by <code>Cursor.SW_RESIZE_CURSOR</code>.
  83.     */
  84.     public static final int    SW_RESIZE_CURSOR         = Cursor.SW_RESIZE_CURSOR;
  85.  
  86.    /**
  87.     * @deprecated   replaced by <code>Cursor.SE_RESIZE_CURSOR</code>.
  88.     */
  89.     public static final int    SE_RESIZE_CURSOR         = Cursor.SE_RESIZE_CURSOR;
  90.  
  91.    /**
  92.     * @deprecated   replaced by <code>Cursor.NW_RESIZE_CURSOR</code>.
  93.     */
  94.     public static final int    NW_RESIZE_CURSOR        = Cursor.NW_RESIZE_CURSOR;
  95.  
  96.    /**
  97.     * @deprecated   replaced by <code>Cursor.NE_RESIZE_CURSOR</code>.
  98.     */
  99.     public static final int    NE_RESIZE_CURSOR         = Cursor.NE_RESIZE_CURSOR;
  100.  
  101.    /**
  102.     * @deprecated   replaced by <code>Cursor.N_RESIZE_CURSOR</code>.
  103.     */
  104.     public static final int    N_RESIZE_CURSOR         = Cursor.N_RESIZE_CURSOR;
  105.  
  106.    /**
  107.     * @deprecated   replaced by <code>Cursor.S_RESIZE_CURSOR</code>.
  108.     */
  109.     public static final int    S_RESIZE_CURSOR         = Cursor.S_RESIZE_CURSOR;
  110.  
  111.    /**
  112.     * @deprecated   replaced by <code>Cursor.W_RESIZE_CURSOR</code>.
  113.     */
  114.     public static final int    W_RESIZE_CURSOR             = Cursor.W_RESIZE_CURSOR;
  115.  
  116.    /**
  117.     * @deprecated   replaced by <code>Cursor.E_RESIZE_CURSOR</code>.
  118.     */
  119.     public static final int    E_RESIZE_CURSOR            = Cursor.E_RESIZE_CURSOR;
  120.  
  121.    /**
  122.     * @deprecated   replaced by <code>Cursor.HAND_CURSOR</code>.
  123.     */
  124.     public static final int    HAND_CURSOR            = Cursor.HAND_CURSOR;
  125.  
  126.    /**
  127.     * @deprecated   replaced by <code>Cursor.MOVE_CURSOR</code>.
  128.     */
  129.     public static final int    MOVE_CURSOR            = Cursor.MOVE_CURSOR;    
  130.  
  131.     public static final int     NORMAL          = 0;
  132.     public static final int     ICONIFIED       = 1;
  133.  
  134.     /**
  135.      * This is the title of the frame.  It can be changed
  136.      * at any time.  <code>title</code> can be null and if
  137.      * this is the case the <code>title</code> = "".
  138.      *
  139.      * @serial
  140.      * @see getTitle()
  141.      * @see setTitle()
  142.      */
  143.     String     title = "Untitled";
  144.     /**
  145.      * <code>icon</code> is the graphical way we can
  146.      * represent the frame.
  147.      * <code>icon</code> can be null, but obviously if
  148.      * you try to set the icon image <code>icon</code>
  149.      * cannot be null.
  150.      *
  151.      * @serial
  152.      * @see getIconImage()
  153.      * @see setIconImage()
  154.      */
  155.     Image      icon;
  156.     /**
  157.      * The frames menubar.  If <code>menuBar</code> = null
  158.      * the frame will not have a menubar.
  159.      *
  160.      * @serial
  161.      * @see getMenuBar()
  162.      * @see setMenuBar()
  163.      */
  164.     MenuBar    menuBar;
  165.     /**
  166.      * This field indicates whether the the frame is resizable
  167.      * This property can be changed at any time.
  168.      * <code>resizable</code> will be true if the frame is
  169.      * resizable, otherwise it will be false.
  170.      *
  171.      * @serial
  172.      * @see isResizable()
  173.      */
  174.     boolean    resizable = true;
  175.     /**
  176.      * <code>mbManagement</code> is only used by the Motif implementation.
  177.      *
  178.      * @serial
  179.      */
  180.     boolean    mbManagement = false;    /* used only by the Motif impl.    */
  181.     private int state = NORMAL;
  182.  
  183.  
  184.     /* 
  185.      * The Windows owned by the Frame.
  186.      * Note: in 1.2 this has been superceded by Window.ownedWindowList
  187.      *
  188.      * @serial
  189.      * @see java.awt.Window#ownedWindowList
  190.      */
  191.     Vector ownedWindows;
  192.  
  193.     /*
  194.      * We insert a weak reference into the Vector of all Frames
  195.      * instead of 'this' so that garbage collection can still take
  196.      * place correctly.
  197.      */
  198.     transient private WeakReference weakThis;
  199.  
  200.     private static final String base = "frame";
  201.     private static int nameCounter = 0;
  202.  
  203.     /*
  204.      * JDK 1.1 serialVersionUID 
  205.      */
  206.      private static final long serialVersionUID = 2673458971256075116L;
  207.  
  208.     static {
  209.         /* ensure that the necessary native libraries are loaded */
  210.     Toolkit.loadLibraries();
  211.     initIDs();
  212.     }
  213.  
  214.     /**
  215.      * Constructs a new instance of <code>Frame</code> that is 
  216.      * initially invisible.  The title of the <code>Frame</code>
  217.      * is empty.
  218.      * @see Component#setSize
  219.      * @see Component#setVisible
  220.      */
  221.     public Frame() {
  222.         this("");
  223.     }
  224.  
  225.     /**
  226.      * Constructs a new, initially invisible <code>Frame</code> object 
  227.      * with the specified title.
  228.      * @param title the title to be displayed in the frame's border.
  229.      *              A <code>null</code> value
  230.      *              is treated as an empty string, "".
  231.      * @see java.awt.Component#setSize
  232.      * @see java.awt.Component#setVisible
  233.      */
  234.     public Frame(String title) {
  235.     this.title = title;
  236.     visible = false;
  237.     setLayout(new BorderLayout());
  238.     weakThis = new WeakReference(this);
  239.         addToFrameList();
  240.     }
  241.  
  242.     /**
  243.      * We have to remove the (hard) reference to weakThis in the
  244.      * Vector, otherwise the WeakReference instance will never get
  245.      * garbage collected.
  246.      */
  247.     protected void finalize() throws Throwable {
  248.         removeFromFrameList();
  249.     super.finalize();
  250.     }
  251.  
  252.     /**
  253.      * Construct a name for this component.  Called by getName() when the
  254.      * name is null.
  255.      */
  256.     String constructComponentName() {
  257.         synchronized (getClass()) {
  258.         return base + nameCounter++;
  259.     }
  260.     }
  261.  
  262.     /**
  263.      * Makes this Frame displayable by connecting it to
  264.      * a native screen resource.  Making a frame displayable will
  265.      * cause any of its children to be made displayable.
  266.      * This method is called internally by the toolkit and should
  267.      * not be called directly by programs.
  268.      * @see Component#isDisplayable
  269.      * @see #removeNotify
  270.      */
  271.     public void addNotify() {
  272.     synchronized (getTreeLock()) {
  273.         if (peer == null) {
  274.         peer = getToolkit().createFrame(this);
  275.         }
  276.         MenuBar menuBar = this.menuBar;
  277.         if (menuBar != null) {
  278.             mbManagement = true;
  279.         menuBar.addNotify();
  280.         ((FramePeer)peer).setMenuBar(menuBar);
  281.         }
  282.         super.addNotify();
  283.     }
  284.     }
  285.  
  286.     /**
  287.      * Gets the title of the frame.  The title is displayed in the
  288.      * frame's border.
  289.      * @return    the title of this frame, or an empty string ("")
  290.      *                if this frame doesn't have a title.
  291.      * @see       java.awt.Frame#setTitle
  292.      */
  293.     public String getTitle() {
  294.     return title;
  295.     }
  296.  
  297.     /**
  298.      * Sets the title for this frame to the specified string.
  299.      * @param    title    the title to be displayed in the frame's border
  300.      * @param title the title to be displayed in the frame's border.
  301.      *              A <code>null</code> value
  302.      *              is treated as an empty string, "".
  303.      * @see      java.awt.Frame#getTitle
  304.      */
  305.     public synchronized void setTitle(String title) {
  306.     this.title = title;
  307.         FramePeer peer = (FramePeer)this.peer;
  308.     if (peer != null) {
  309.         peer.setTitle(title);
  310.     }
  311.     }
  312.  
  313.     /**
  314.      * Gets the image to be displayed in the minimized icon
  315.      * for this frame.
  316.      * @return    the icon image for this frame, or <code>null</code> 
  317.      *                    if this frame doesn't have an icon image.
  318.      * @see       java.awt.Frame#setIconImage
  319.      */
  320.     public Image getIconImage() {
  321.     return icon;
  322.     }
  323.  
  324.     /**
  325.      * Sets the image to displayed in the minimized icon for this frame. 
  326.      * Not all platforms support the concept of minimizing a window.
  327.      * @param     image the icon image to be displayed.
  328.      *            If this parameter is <code>null</code> then the
  329.      *            icon image is set to the default image, which may vary
  330.      *            with platform.            
  331.      * @see       java.awt.Frame#getIconImage
  332.      */
  333.     public synchronized void setIconImage(Image image) {
  334.     this.icon = image;
  335.         FramePeer peer = (FramePeer)this.peer;
  336.     if (peer != null) {
  337.         peer.setIconImage(image);
  338.     }
  339.     }
  340.  
  341.     /**
  342.      * Gets the menu bar for this frame.
  343.      * @return    the menu bar for this frame, or <code>null</code> 
  344.      *                   if this frame doesn't have a menu bar.
  345.      * @see       java.awt.Frame#setMenuBar
  346.      */
  347.     public MenuBar getMenuBar() {
  348.     return menuBar;
  349.     }
  350.  
  351.     /**
  352.      * Sets the menu bar for this frame to the specified menu bar.
  353.      * @param     mb the menu bar being set.
  354.      *            If this parameter is <code>null</code> then any
  355.      *            existing menu bar on this frame is removed.
  356.      * @see       java.awt.Frame#getMenuBar
  357.      */
  358.     public void setMenuBar(MenuBar mb) {
  359.         synchronized (getTreeLock()) {
  360.         if (menuBar == mb) {
  361.             return;
  362.         }
  363.         if ((mb != null) && (mb.parent != null)) {
  364.             mb.parent.remove(mb);
  365.         }
  366.         if (menuBar != null) {
  367.             remove(menuBar);
  368.         }
  369.         menuBar = mb;
  370.         if (menuBar != null) {
  371.             menuBar.parent = this;
  372.  
  373.         FramePeer peer = (FramePeer)this.peer;
  374.         if (peer != null) {
  375.             mbManagement = true;
  376.             menuBar.addNotify();
  377.             if (valid) {
  378.                 invalidate();
  379.             }
  380.             peer.setMenuBar(menuBar);
  381.         }
  382.         }
  383.     }
  384.     }
  385.  
  386.     /**
  387.      * Indicates whether this frame is resizable by the user.  
  388.      * By default, all frames are initially resizable. 
  389.      * @return    <code>true</code> if the user can resize this frame; 
  390.      *                        <code>false</code> otherwise.
  391.      * @see       java.awt.Frame#setResizable
  392.      */
  393.     public boolean isResizable() {
  394.     return resizable;
  395.     }
  396.  
  397.     /**
  398.      * Sets whether this frame is resizable by the user.  
  399.      * @param    resizable   <code>true</code> if this frame is resizable; 
  400.      *                       <code>false</code> otherwise.
  401.      * @see      java.awt.Frame#isResizable
  402.      */
  403.     public void setResizable(boolean resizable) {
  404.         boolean testvalid = false;
  405.  
  406.         synchronized (this) {
  407.         this.resizable = resizable;
  408.         FramePeer peer = (FramePeer)this.peer;
  409.         if (peer != null) {
  410.             peer.setResizable(resizable);
  411.         testvalid = true;
  412.         }
  413.     }
  414.  
  415.     // On some platforms, changing the resizable state affects
  416.     // the insets of the Frame. If we could, we'd call invalidate()
  417.     // from the peer, but we need to guarantee that we're not holding
  418.     // the Frame lock when we call invalidate().
  419.     if (testvalid && valid) {
  420.         invalidate();
  421.     }
  422.     }
  423.  
  424.     /**
  425.      * Sets the state of this frame.
  426.      * @return   state   <code>Frame.ICONIFIED</code> if frame in iconic state;
  427.      *                   <code>Frame.NORMAL</code> if frame is in normal state.
  428.      * @see      java.awt.Frame#getState
  429.      */
  430.     public synchronized void setState(int state) {
  431.         this.state = state;
  432.         FramePeer peer = (FramePeer)this.peer;
  433.         if (peer != null) {
  434.             peer.setState(state);
  435.         }
  436.     }
  437.  
  438.     /**
  439.      * Gets the state of this frame.
  440.      * @param    <code>Frame.ICONIFIED</code> if this frame is in iconic state;
  441.      *           <code>Frame.NORMAL</code> if this frame is in normal state.
  442.      * @see      java.awt.Frame#setState
  443.      */
  444.     public synchronized int getState() {
  445.         FramePeer peer = (FramePeer)this.peer;
  446.         if (peer != null) {
  447.             state = peer.getState();
  448.         }
  449.         return state;
  450.     }
  451.  
  452.     /**
  453.      * Removes the specified menu bar from this frame.
  454.      * @param    m   the menu component to remove.
  455.      *           If this parameter is <code>null</code> then a
  456.      *           NullPointerException is thrown and no action
  457.      *           is taken.
  458.      */
  459.     public void remove(MenuComponent m) {
  460.     synchronized (getTreeLock()) {
  461.         if (m == menuBar) {
  462.         menuBar = null;
  463.         FramePeer peer = (FramePeer)this.peer;
  464.         if (peer != null) {
  465.             mbManagement = true;
  466.             if (valid) {
  467.                 invalidate();
  468.             }
  469.             peer.setMenuBar(null);
  470.             m.removeNotify();
  471.         }
  472.         m.parent = null;
  473.         } else {
  474.         super.remove(m);
  475.         }
  476.     }
  477.     }
  478.  
  479.     /**
  480.      * Makes this Frame undisplayable by removing its connection
  481.      * to its native screen resource. Making a Frame undisplayable
  482.      * will cause any of its children to be made undisplayable. 
  483.      * This method is called by the toolkit internally and should
  484.      * not be called directly by programs.
  485.      * @see Component#isDisplayable
  486.      * @see #addNotify
  487.      */
  488.     public void removeNotify() {
  489.         synchronized (getTreeLock()) {
  490.         FramePeer peer = (FramePeer)this.peer;
  491.         if (peer != null) {
  492.                 // get the latest Frame state before disposing
  493.                 getState();
  494.  
  495.                 if (menuBar != null) {
  496.                 mbManagement = true;
  497.             peer.setMenuBar(null);
  498.             menuBar.removeNotify();
  499.                 }
  500.         }
  501.         super.removeNotify();
  502.     }
  503.     }
  504.  
  505.     void postProcessKeyEvent(KeyEvent e) {
  506.         if (menuBar != null && menuBar.handleShortcut(e)) {
  507.             e.consume();
  508.             return;
  509.         }
  510.         super.postProcessKeyEvent(e);
  511.     }
  512.  
  513.     /**
  514.      * Returns the parameter String of this Frame.
  515.      */
  516.     protected String paramString() {
  517.     String str = super.paramString();
  518.     if (resizable) {
  519.         str += ",resizable";
  520.     }
  521.     if (title != null) {
  522.         str += ",title=" + title;
  523.     }
  524.     return str;
  525.     }
  526.  
  527.     /**
  528.      * @deprecated As of JDK version 1.1,
  529.      * replaced by <code>Component.setCursor(Cursor)</code>.
  530.      */
  531.     public synchronized void setCursor(int cursorType) {
  532.     if (cursorType < DEFAULT_CURSOR || cursorType > MOVE_CURSOR) {
  533.         throw new IllegalArgumentException("illegal cursor type");
  534.     }
  535.     setCursor(Cursor.getPredefinedCursor(cursorType));
  536.     }
  537.  
  538.     /**
  539.      * @deprecated As of JDK version 1.1,
  540.      * replaced by <code>Component.getCursor()</code>.
  541.      */
  542.     public int getCursorType() {
  543.     return (getCursor().getType());
  544.     }
  545.  
  546.     /**
  547.      * Returns an array containing all Frames created by the application.
  548.      * If called from an applet, the array will only include the Frames
  549.      * accessible by that applet.
  550.      * @since JDK1.2
  551.      */
  552.     public static Frame[] getFrames() {
  553.         synchronized (Frame.class) {
  554.             Frame realCopy[];
  555.             Vector frameList =
  556.         (Vector)AppContext.getAppContext().get(Frame.class);
  557.             if (frameList != null) {
  558.             // Recall that frameList is actually a Vector of WeakReferences
  559.             // and calling get() on one of these references may return
  560.             // null. Make two arrays-- one the size of the Vector 
  561.             // (fullCopy with size fullSize), and one the size of all
  562.             // non-null get()s (realCopy with size realSize).
  563.             int fullSize = frameList.size();
  564.         int realSize = 0;
  565.         Frame fullCopy[] = new Frame[fullSize];
  566.  
  567.         for (int i = 0; i < fullSize; i++) {
  568.             fullCopy[realSize] = (Frame) 
  569.                 (((WeakReference) (frameList.elementAt(i))).get());
  570.  
  571.             if (fullCopy[realSize] != null) {
  572.                 realSize++;
  573.             }
  574.         }
  575.  
  576.         if (fullSize != realSize) {
  577.             realCopy = new Frame[realSize];
  578.             System.arraycopy(fullCopy, 0, realCopy, 0, realSize);
  579.         } else {
  580.             realCopy = fullCopy;
  581.         }
  582.             } else {
  583.                 realCopy = new Frame[0];
  584.             }
  585.             return realCopy;
  586.         }
  587.     }
  588.  
  589.     void addToFrameList() {
  590.         synchronized (Frame.class) {
  591.             Vector frameList = (Vector)appContext.get(Frame.class);
  592.             if (frameList == null) {
  593.                 frameList = new Vector();
  594.                 appContext.put(Frame.class, frameList);
  595.             }
  596.             frameList.addElement(weakThis);
  597.         }
  598.     }
  599.  
  600.     void removeFromFrameList() {
  601.         synchronized (Frame.class) {
  602.             Vector frameList = (Vector)appContext.get(Frame.class);
  603.             if (frameList != null) {
  604.                 frameList.removeElement(weakThis);
  605.             }
  606.         }
  607.     }
  608.  
  609.     /* Serialization support.  If there's a MenuBar we restore
  610.      * its (transient) parent field here.  Likewise for top level 
  611.      * windows that are "owned" by this frame.
  612.      */
  613.  
  614.     /**
  615.      * Frame Serialized Data Version.
  616.      *
  617.      * @serial
  618.      */
  619.     private int frameSerializedDataVersion = 1;
  620.  
  621.     /**
  622.      * Writes default serializable fields to stream.  Writes
  623.      * a list of serializable ItemListener(s) as optional data.
  624.      * The non-serializable ItemListner(s) are detected and
  625.      * no attempt is made to serialize them.
  626.      *
  627.      * @serialData Null terminated sequence of 0 or more pairs.
  628.      *             The pair consists of a String and Object.
  629.      *             The String indicates the type of object and
  630.      *             is one of the following :
  631.      *             itemListenerK indicating and ItemListener object.
  632.      *
  633.      * @see java.awt.Component.itemListenerK
  634.      */
  635.     private void writeObject(ObjectOutputStream s)
  636.       throws IOException 
  637.     {
  638.       s.defaultWriteObject();
  639.     }
  640.  
  641.     /**
  642.      * Read the ObjectInputStream and if it isnt null
  643.      * add a listener to receive item events fired
  644.      * by the Frame.
  645.      * Unrecognised keys or values will be Ignored.
  646.      * @see removeActionListener()
  647.      * @see addActionListener()
  648.      */
  649.     private void readObject(ObjectInputStream s)
  650.       throws ClassNotFoundException, IOException 
  651.     {
  652.       s.defaultReadObject();
  653.  
  654.       if (menuBar != null)
  655.     menuBar.parent = this;
  656.  
  657.       // Ensure 1.1 serialized Frames can read & hook-up
  658.       // owned windows properly
  659.       //
  660.       if (ownedWindows != null) {
  661.           for (int i = 0; i < ownedWindows.size(); i++) {
  662.           connectOwnedWindow((Window) ownedWindows.elementAt(i));
  663.       }
  664.           ownedWindows = null;  
  665.       }
  666.  
  667.       weakThis = new WeakReference(this);
  668.       addToFrameList();
  669.     }
  670.     /**
  671.      * Initialize JNI field and method IDs
  672.      */
  673.     private static native void initIDs();
  674.  
  675. }
  676.